package com.awesome.network.util;

import com.google.gson.GsonBuilder;
import com.google.gson.LongSerializationPolicy;
import com.awesome.network.callback.OnProgressListener;
import com.awesome.network.request.UploadRequestBody;

import java.io.File;
import java.util.Map;

import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;


/**
 * Author: JFangZ
 * Email:janezhang1901@163.com
 * Date: 2021/4/28 18:31
 * Description:
 */
public class RequestFactory {
    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2021/4/30 9:51
     * Description:Create instance for get request.
     *
     * @param url       请求地址
     * @param headerMap 请求头
     * @param paramMap  请求参数
     * @return 用于发起请求的对象
     */
    public static Request newGetRequest(String url, Map<String, String> headerMap, Map<String, Object> paramMap) throws Exception {
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) {
            throw new Exception("Illegal url");
        }
        // Add params.
        HttpUrl.Builder httpUrlBuilder = httpUrl.newBuilder();
        for (String key : paramMap.keySet()) {
            Object value = paramMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            httpUrlBuilder.addQueryParameter(key, value.toString());
        }
        // Add header.
        Request.Builder requestBuilder = new Request.Builder();
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(httpUrlBuilder.build())
                .get()
                .build();
    }

    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2021/4/30 9:51
     * Description:Create instance for download request.
     *
     * @param url 请求地址
     * @return 用于发起请求的对象
     */
    public static Request newGetDownloadRequest(String url, Map<String, String> headerMap, Map<String, Object> paramMap) {
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) {
            return null;
        }
        // Add params.
        HttpUrl.Builder httpUrlBuilder = httpUrl.newBuilder();
        for (String key : paramMap.keySet()) {
            Object value = paramMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            httpUrlBuilder.addQueryParameter(key, value.toString());
        }
        // Add headers.
        Request.Builder requestBuilder = new Request.Builder();
        requestBuilder.addHeader("Accept-Encoding", "dentity");
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(httpUrlBuilder.build())
                .get()
                .build();
    }

    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2021/4/30 9:51
     * Description:Create instance for post request.
     *
     * @param url          请求地址
     * @param parameterMap 请求参数
     * @return 用于发起请求的对象
     */
    public static Request newPostRequest(String url, Map<String, String> headerMap, Map<String, Object> parameterMap) {
        // Add params.
        StringBuilder paramStringBuilder = new StringBuilder();
        for (String key : parameterMap.keySet()) {
            paramStringBuilder.append(key).append("=").append(parameterMap.get(key)).append("&");
        }
        if (paramStringBuilder.lastIndexOf("&") != -1) {
            paramStringBuilder.deleteCharAt(paramStringBuilder.lastIndexOf("&"));
        }
        // Add headers.
        Request.Builder requestBuilder = new Request.Builder();
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(url)
                .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=utf-8"), paramStringBuilder.toString()))
                .build();
    }

    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2021/4/30 9:51
     * Description:Create instance for post request and Content-Type is application/json.
     *
     * @param url      请求地址
     * @param paramMap 请求参数
     * @return 用于发起请求的对象
     */
    public static Request newPostJsonRequest(String url, Map<String, String> headerMap, Map<String, Object> paramMap) {
        // Add headers.
        Request.Builder requestBuilder = new Request.Builder();
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(url)
                .post(RequestBody.create(MediaType.parse("application/json;charset=utf-8"), new GsonBuilder()
                        .setLongSerializationPolicy(LongSerializationPolicy.STRING) //转换 Long 类型参数时先转为 String,否则数字太长会自动转为科学计数法
                        .create()
                        .toJson(paramMap)))
                .addHeader("Accept-Language", "zh_CN")
                .build();
    }

    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2019/7/5 15:24
     * Description:Create instance for upload file by form-data.
     *
     * @param url      请求地址
     * @param paramMap 请求参数
     * @return 用于发起请求的对象
     */
    public static Request newPostFileRequest(String url
            , Map<String, String> headerMap
            , Map<String, Object> paramMap
            , OnProgressListener onProgressListener) {
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
        multipartBodyBuilder.setType(MultipartBody.FORM);
        for (String key : paramMap.keySet()) {
            Object value = paramMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            if (value instanceof File) {
                File file = (File) value;
                multipartBodyBuilder.addFormDataPart(key
                        , file.getName()
                        , new UploadRequestBody(file, "application/octet-stream", onProgressListener));
            } else {
                multipartBodyBuilder.addFormDataPart(key
                        , value.toString());
            }
        }
        // Add headers.
        Request.Builder requestBuilder = new Request.Builder();
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(url)
                .post(multipartBodyBuilder.build())
                .build();
    }

    /**
     * Author: JFangZ
     * Email:janezhang1901@163.com
     * Date:2019/7/5 15:24
     * Description:Create instance for upload file,not form-data.
     *
     * @param url      请求地址
     * @param paramMap 请求参数
     * @return 用于发起请求的对象
     */
    public static Request newPostFileRequestBinary(String url
            , Map<String
            , String> headerMap, Map<String, Object> paramMap
            , OnProgressListener onProgressListener) {
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl == null) {
            return null;
        }
        File file = null;
        // Add params.
        HttpUrl.Builder httpUrlBuilder = httpUrl.newBuilder();
        for (String key : paramMap.keySet()) {
            Object value = paramMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            if (value instanceof File) {
                file = (File) value;
                continue;
            }
            httpUrlBuilder.addQueryParameter(key, value.toString());
        }
        // Add headers.
        Request.Builder requestBuilder = new Request.Builder();
        for (String key : headerMap.keySet()) {
            String value = headerMap.get(key);
            if (key == null || value == null) {
                continue;
            }
            requestBuilder.addHeader(key, value);
        }
        return requestBuilder
                .url(httpUrlBuilder.build())
                .post(new UploadRequestBody(file
                        , "application/octet-stream"
                        , onProgressListener))
                .build();
    }
}
